home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / ascutils.zip / TABSPC.ASM < prev    next >
Assembly Source File  |  1988-05-23  |  4KB  |  192 lines

  1. PAGE 55,130
  2. ;
  3. ;                TABSPC
  4. ;
  5.  
  6. bufspc        equ    0400h
  7. stkspc        equ    0100h
  8. midbuf        equ    0200h
  9.  
  10.  
  11. codeseg        segment
  12.         assume    cs:codeseg, ds:codeseg
  13.  
  14.  
  15.         org    100h
  16.  
  17. tabspc        proc    far
  18.  
  19. start:        jmp    init
  20.  
  21. errmsg1        db    0Dh, 0Ah, 'Read    Error',    0Dh, 0Ah, '$'
  22. errmsg2        db    0Dh, 0Ah, 'Could not get enough    memory.', 0Dh, 0Ah, '$'
  23. help_msg    db    0Dh, 0Ah, 'TABSPC is a filter that converts all    TABs'
  24.         db    ' in the standard input    to spaces in', 0Dh, 0Ah
  25.         db    'the standard output.',    0Dh, 0Ah, 0Dh, 0Ah
  26.         db    'Usage:    TABSPC [<fname]    [>fname]', 0Dh,    0Ah, '$'
  27. errmsg3        db    0Dh, 0Ah, 'Write Error', 0Dh, 0Ah, '$'
  28.  
  29. ; Note - space for the 1024 byte buffer    and the    256 byte stack is allocated
  30. ;    here, rather than being    stored in the task image on disk.
  31. ;
  32.  
  33. init:        mov    bx,offset buffer + bufspc + stkspc    ; req'd    memory
  34.         add    bx,010h
  35.         mov    cl,4
  36.         shr    bx,cl            ; get it in paragraphs
  37.         mov    ah,04Ah            ; set it - cf=1    if error
  38.         int    021h
  39.         mov    dx,offset errmsg2    ; setup    err msg    if needed
  40.         jc    err_exit        ; exit with error message.
  41.         mov    ax,0
  42.         mov    di,offset buffer    ; else initialize buffer and
  43.         mov    cx,bufspc + stkspc    ;  stack space to 0's
  44.         shr    cx,1
  45.         cld
  46.         rep    stosw
  47.         mov    sp,offset buffer + bufspc + stkspc    ; init sp
  48.         mov    si,80h            ; get cmd line char count
  49.         cmp    byte ptr [si],0        ; into cx and incr by 1
  50.         je    Main            ; - char count 0, skip next
  51.         mov    cl,[si]
  52.         inc    cx
  53.  
  54. skpspc:        inc    si            ; skip over blanks
  55.         cmp    byte ptr [si],20h
  56.         loopz    skpspc
  57.  
  58.         jcxz    Main            ; skip to Main if out of chars
  59.         cmp    byte ptr [si],3Fh    ; '?' (for help)
  60.         jne    Main            ; no, ignore any others.
  61.         mov    dx,offset help_msg    ; output help msg to std error
  62.         jmp    short err_exit
  63.  
  64. Main:        call    get_line    ; get a    line from std input
  65.         jc    err_exit    ; cf=1 if error
  66.         or    ax,ax        ; ax=0 if eof (not error)
  67.         jz    norm_exit
  68.         call    fix_line    ; convert tabs to spaces
  69.         call    put_line    ; write    to std output
  70.         jc    err_exit    ; cf=1 is error
  71.         jmp    short Main    ; continue.
  72.  
  73. err_exit:    mov    di,dx        ; point    di to error message
  74.         mov    cx,0FFh        ; set cx to 255    (arbitrary limit)
  75.         mov    al,024h        ; "$" line terminator
  76.         cld            ; clear    direction flag
  77.         repnz    scasb        ; scan message for char    count
  78.         dec    di        ; decr by 1 to leave out "$"
  79.         mov    cx,di        ; arith. to get    char count into    cx
  80.         sub    cx,dx
  81.         mov    bx,2        ; std error handle
  82.         mov    ah,040h        ; output message.
  83.         int    021h
  84.         mov    al,1        ; set exit status to 1 on error
  85.  
  86. norm_exit:    mov    ah,04Ch        ; program terminate.
  87.         int    021h
  88.  
  89. tabspc        endp
  90.  
  91.  
  92. ;        SUBROUTINE
  93. ;        gets a line from std input.
  94.  
  95. get_line    proc    near
  96.         mov    si,offset buffer
  97.  
  98. get_1:        mov    dx,si            ; point    to input buffer
  99.         mov    bx,0            ; std input handle
  100.         mov    cx,1            ; char count = 1
  101.         mov    ah,03Fh            ; input    a char
  102.         int    021h
  103.         jc    get_err            ; cf=1 if error
  104.         cmp    byte ptr [si],0Ah    ; eoln ?
  105.         je    get_ok
  106.         or    ax,ax            ; ax=0 if kybd eof
  107.         jz    get_ok
  108.         xor    ax,ax            ; make ax=0 on eof (disk)
  109.         cmp    byte ptr [si],1Ah
  110.         je    get_ok
  111.         inc    si            ; incr pointer to next loc.
  112.         jmp    short get_1        ; and continue.
  113.  
  114. get_ok:        clc
  115.         ret
  116.  
  117. get_err:    mov    dx,offset errmsg1    ; read error.
  118.         stc
  119.         ret
  120.  
  121. get_line    endp
  122.  
  123.  
  124. ;        SUBROUTINE
  125. ;        This is    where the transformation takes place.
  126. ;        Have fun.
  127. ;
  128.  
  129. fix_line    proc    near
  130.         push    ax
  131.         mov    si,offset buffer
  132.         mov    di,offset buffer + midbuf
  133.         mov    dx,di
  134.  
  135. fixloop:    lodsb
  136.         cmp    al,9
  137.         je    fix_1
  138.         stosb
  139.         cmp    al,0Ah
  140.         je    fix_2
  141.         jmp    short fixloop
  142.  
  143. fix_1:        mov    cx,di
  144.         sub    cx,dx
  145.         add    cx,8
  146.         and    cx,0FFF8h
  147.         add    cx,dx
  148.         sub    cx,di
  149.         mov    al,20h
  150.         rep    stosb
  151.         jmp    short fixloop
  152.  
  153. fix_2:        pop    ax
  154.         mov    cx,di
  155.         sub    cx,dx
  156.         ret
  157.  
  158. fix_line    endp
  159.  
  160.  
  161. ;        SUBROUTINE
  162. ;        Outputs    a line to std output
  163. ;
  164.  
  165. put_line    proc    near
  166.         jcxz    put_ok                ; no chars? exit.
  167.         push    cx                ; save char count
  168.         mov    dx,offset buffer + midbuf    ; point    to out buffer
  169.         mov    bx,1                ; std out handle
  170.         mov    ah,040h                ; output cx chars
  171.         int    021h
  172.         pop    cx                ; restore cx
  173.         jc    put_err                ; cf=1 if error    ocurred
  174.         sub    cx,ax                ; ax=cx    if ok.
  175.         jnz    put_err
  176.  
  177. put_ok:        clc
  178.         ret
  179.  
  180. put_err:    mov    dx,offset errmsg3    ; write    error
  181.         stc
  182.         ret
  183.  
  184. put_line    endp
  185.  
  186.  
  187. buffer        db    0        ; marker to set    up buffer and stack
  188.                     ; when program begins execution.
  189.  
  190. codeseg        ends
  191.         end    start
  192.